package com.tqjc.system.system.service.impl;

import cn.hutool.core.collection.CollUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.tqjc.system.common.constant.AddTaskConstant;
import com.tqjc.system.common.constant.ConfigConstant;
import com.tqjc.system.common.constant.GlobalConstant;
import com.tqjc.system.common.constant.RemoteURLConstant;
import com.tqjc.system.common.entity.BO.*;
import com.tqjc.system.common.enums.*;
import com.tqjc.system.common.enums.pipeline.BusinessCode;
import com.tqjc.system.core.pipeline.ProcessContext;
import com.tqjc.system.core.pipeline.ProcessMachine;
import com.tqjc.system.core.pipeline.service.CarExecuteTaskAction;
import com.tqjc.system.core.pipeline.thread.AbstrCarDoingAddTaskThread;
import com.tqjc.system.core.pipeline.thread.AddTaskGuardThread;
import com.tqjc.system.core.pipeline.thread.CarDoingAddTaskThread;
import com.tqjc.system.core.pipeline.thread.CarDoingSingleAddTaskThread;
import com.tqjc.system.core.pipeline.util.AddTaskUtil;
import com.tqjc.system.core.pipeline.util.ScanUtils;
import com.tqjc.system.core.threadpool.ThreadPoolManager;
import com.tqjc.system.core.util.DateUtils;
import com.tqjc.system.core.util.PLCHttpsUtils;
import com.tqjc.system.core.util.SpringUtils;
import com.tqjc.system.system.asyn.AsynTaskExecuteThread;
import com.tqjc.system.system.entity.SysAddDetailTaskEntity;
import com.tqjc.system.system.entity.SysAddPrimaryTaskEntity;
import com.tqjc.system.system.entity.SysMessageRecordEntity;
import com.tqjc.system.system.model.vo.TaskMaterialEditVO;
import com.tqjc.system.system.model.vo.TaskMaterialOptVO;
import com.tqjc.system.system.service.SysAddDetailTaskService;
import com.tqjc.system.system.service.SysAddPrimaryTaskService;
import com.tqjc.system.system.service.SysBusinessTaskService;
import com.tqjc.system.system.service.SysMessageRecordService;
import com.tqjc.system.system.util.SystemUtils;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.text.DecimalFormat;
import java.time.LocalDateTime;
import java.util.*;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.locks.ReentrantLock;

/**
 * @author 86195
 * @version 1.0
 * @description 任务业务服务类
 * @date 2023/10/16 15:21
 */
@Service("SysBusinessTaskService")
@Slf4j
public class SysBusinessTaskServiceImpl implements SysBusinessTaskService {

    @Autowired
    private SysAddPrimaryTaskService primaryTaskService;

    @Autowired
    private SysAddDetailTaskService detailTaskService;

    @Autowired
    private SysMessageRecordService recordService;

    @Autowired
    private ProcessMachine processMachine;

    @Autowired
    private CarExecuteTaskAction carExecuteTaskAction;





    @Override
    public void completeTask(String msgBody) {
        String slotNo = msgBody.substring(0, 2).trim();
        //1.翻转总任务的状态
        primaryTaskService.complete(slotNo, TaskStatusEnum.STATUS_COMPLETE.getStatus());

        TankCarNoEnum tankCarNoEnum = TankCarNoEnum.getEnum(slotNo);
        TankCarTaskInfoBO taskInfoBO = TankCarTaskInfoBO.builder().taskType(AddTaskConstant.TANK_CAR_TASK_TYPE_UNLOAD).spanNo(slotNo).build();
        //添加至槽车队列中，槽车移动
        AddTaskConstant.TANK_CAR_QUEUE_MAP.get(tankCarNoEnum.getTankCarNo()).add(taskInfoBO);

    }

    @Override
    public void accept(String message) {
       //报文长度
        int length = Integer.valueOf(message.substring(0, 4));
        //电文号
        String msgNo = message.substring(4, 10);
        //发送时间  年
        int yearStr = Integer.valueOf(message.substring(10, 14));
        //发送时间  月
        int monthStr = Integer.valueOf(message.substring(14, 16));
        //发送时间  日
        int datStr = Integer.valueOf(message.substring(16, 18));
        //发送时间  时
        int hourStr = Integer.valueOf(message.substring(18, 20));
        //发送时间  分
        int minuteStr = Integer.valueOf(message.substring(20, 22));
        //发送时间  秒
        int secondStr = Integer.valueOf(message.substring(22, 24));
        LocalDateTime sendDate = LocalDateTime.of(yearStr, monthStr, datStr, hourStr, minuteStr, secondStr);

        //yyyy-MM-dd HH:mm:ss

        log.info("接受报文任务开始，发送时间为：{}",sendDate);
        //发送方code
        String send = message.substring(24, 26);
        //接受方code
        String accept = message.substring(26, 28);
        //传送功能码
        String sendCode = message.substring(28, 29);
        //电文体
        String msgBody = message.substring(29,message.length());
        SysMessageRecordEntity sysMessageRecord = SysMessageRecordEntity.builder().accept(accept).send(send)
                .sendCode(sendCode).messageBody(msgBody).sendDate(sendDate).msgNo(msgNo).msgLength(length).build();

        recordService.insert(sysMessageRecord);
        //信息状态初始为成功
        SysMessageRecordEntity updateEntity = SysMessageRecordEntity.builder().idKey(sysMessageRecord.getIdKey())
                .status(MsgStatusEnum.SUCC.getStatus()).build();
        try {

            if(GlobalConstant.COMPLETE_MSG_NO.equals(msgNo)){
                //任务完成
                this.completeTask(msgBody);
            } else if(GlobalConstant.TASK_MSG_NO.equals(msgNo)) {
                //其他任务下发
                handleTask(msgBody,sysMessageRecord.getIdKey());

            } else {
                throw new Exception("无对应的报文号类型");
            }
            log.info("接受报文任务结束，发送时间为：{}",sendDate);

        } catch (Exception e){
            log.error("接受报文任务异常,发送时间为："+sendDate,e);
            updateEntity.setStatus(MsgStatusEnum.ERR.getStatus());
            String errMsg = e.getMessage();
            updateEntity.setErrMsg(errMsg.length() > 200 ? errMsg.substring(0,200) : errMsg);
        }
        //翻转信息状态
        recordService.updateById(updateEntity);

    }


    private void handleTask(String msgBody,long idKey) {
        //解析任务类型
        String opFlag = msgBody.substring(2, 3);
        //获取对应的任务类型枚举
        TaskTypeEnum taskTypeEnum = TaskTypeEnum.getEnumByType(opFlag);
        //执行任务逻辑
        taskTypeEnum.handle(this,msgBody,idKey);

    }

    public void increase(TaskMaterialOptVO taskMaterialOptVO){
        String tankCarNo = taskMaterialOptVO.getTankCarNo();
        List<SysAddDetailTaskEntity> list = detailTaskService.getDetailTaskInfo(tankCarNo,AddTaskConstant.TEMP_TASK_ID);
        List<SysAddDetailTaskEntity> updateList = new ArrayList<>(list.size());
        //子任务个数
        int num = list.size();

        SysAddPrimaryTaskEntity primaryTaskEntity = SysAddPrimaryTaskEntity.builder()
                .status(TaskStatusEnum.STATUS_DOING.getStatus()).taskType(AddTaskConstant.TASK_TYPE_TQ)
                .materialNum(num).distributeDate(LocalDateTime.now()).tankCarNo(tankCarNo).build();
        primaryTaskService.save(primaryTaskEntity);
        String taskId = String.valueOf(primaryTaskEntity.getIdKey());
        list.forEach( e ->{
            e.setTaskId(taskId);
            updateList.add(e);
        });
        detailTaskService.updateBatchById(updateList);
        AddBusinessTaskInfo taskInfo = AddBusinessTaskInfo.builder().taskId(taskId).tankCarNo(tankCarNo)
                .workingSpanNo(taskMaterialOptVO.getSpanNo()).test("1").build();
        if(!AddTaskConstant.CAR_NO_BOTH.equals(taskMaterialOptVO.getCarNo())){
            taskInfo.setFlag(true);
            taskInfo.setCarNo(taskMaterialOptVO.getCarNo());
        }

        this.executeHandTask(taskInfo);
    }

    @Override
    public void frontDel(TaskMaterialOptVO taskMaterialOptVO) {
        //主表更改子任务数量
        String taskId = taskMaterialOptVO.getTaskId();
        //子任务的主键
        String idKey = taskMaterialOptVO.getIdKey();
        detailTaskService.deleteMaterial(idKey);
    }

    @Override
    public void executeHandTask(AddBusinessTaskInfo content) {
        boolean flag = content.isFlag();
        String taskId = content.getTaskId();
        String workingSpanNo = content.getWorkingSpanNo();
        String tankCarNo = content.getTankCarNo();
        log.info("加料任务taskId：{},对工作跨:{}的天桥系统自己下发任务开始", taskId, workingSpanNo);
        //工作跨
        //获取排序任务物料  未完成的物料  升序
        List<TaskMaterialBO> workingMaterialList = detailTaskService.sortSpanTaskMaterialList(workingSpanNo, taskId);

        //从集合取出排序最小值有排序最大值
        int size = workingMaterialList.size();

        //若集合还存在物料，缓存该集合为后续线程共享变量   key:taskId   value:workingMaterialList
        AddTaskUtil.TASK_WORKING_MATERIAL_MAP.put(taskId, workingMaterialList);

        //本跨状态变成忙碌状态
        AddTaskUtil.updateSpanNoStatus(workingSpanNo,AddTaskConstant.SPAN_STATUS_WORK);

        //更改槽车扫描标识
        ScanUtils.setTankCarScanActFinish(TankCarNoEnum.getEnumByCarNo(content.getTankCarNo()),false);

        //添加至槽车队列中
        TankCarTaskInfoBO infoBO = TankCarTaskInfoBO.builder().taskType(AddTaskConstant.TANK_CAR_TASK_TYPE_ADD).spanNo(workingSpanNo).build();
        AddTaskConstant.TANK_CAR_QUEUE_MAP.get(tankCarNo).add(infoBO);

        if (flag) {

            //指定天车干活
            while (workingMaterialList.size() != 0){

                TaskMaterialBO taskMaterialBO = workingMaterialList.get(0);
                workingMaterialList.remove(0);
                CarEnum carEnum = CarEnum.getCarEnumByCarNo(content.getCarNo());
                //当前子任务只有一个,派发一台合理的天车  根据任务物料库区位置，选择合适天车
                SingleTaskMaterialBO singleTaskMaterialBO = SingleTaskMaterialBO.builder().taskId(taskId)
                        .workingSpanNo(workingSpanNo).materialNo(taskMaterialBO.getWorkinMaterialNo()).tankCarNo(content.getTankCarNo())
                        .carEnum(carEnum).idKey(taskMaterialBO.getIdKey()).areaNum(taskMaterialBO.getAreaNum()).build();
                //异常启动线程干活
                String threadKey = CarPLCInfoEnum.getCarNoEnum(workingSpanNo, carEnum.getCarNo()).getMacSN();
                CarDoingSingleAddTaskThread thread = CarDoingSingleAddTaskThread.builder().tankCarReadyFlag(true).taskMaterialBO(singleTaskMaterialBO).build();
                thread.setTaskId(taskId);
                AddTaskConstant.CAR_THREAD_MAP.put(threadKey,thread);
                thread.start();
                while (true) {
                    if (thread.isTaskFinishFlag()) {
                        log.info("加料任务taskId：{},对工作跨:{}的天桥系统自己下发任务,单线程干活完成", taskId, workingSpanNo);
                        AddTaskConstant.CAR_THREAD_MAP.remove(threadKey);
                        break;
                    }
                    try {

                        Thread.sleep(3*1000);
                    } catch (Exception e){
                        log.error("加料任务taskId：{},对工作跨:{}的天桥系统自己下发任务,单线程出现异常", taskId, workingSpanNo,e);
                    }
                }
            }

        } else {
            MoreTaskMaterialBO taskMaterialBO1 = MoreTaskMaterialBO.builder().taskId(taskId).test(content.getTest())
                    .workingSpanNo(workingSpanNo).tankCarNo(content.getTankCarNo()).carEnum(CarEnum.CAR_NO_1).build();
            ReentrantLock lock = new ReentrantLock();
            CarDoingAddTaskThread t1 = CarDoingAddTaskThread.builder().lock(lock).tankCarReadyFlag(true).taskMaterialBO(taskMaterialBO1).build();
            MoreTaskMaterialBO taskMaterialBO2 = MoreTaskMaterialBO.builder().taskId(taskId).test(content.getTest())
                    .workingSpanNo(workingSpanNo).tankCarNo(content.getTankCarNo()).carEnum(CarEnum.CAR_NO_2).build();
            t1.setTaskId(taskId);
            CarDoingAddTaskThread t2 = CarDoingAddTaskThread.builder().lock(lock).tankCarReadyFlag(true).taskMaterialBO(taskMaterialBO2).build();
            t2.setTaskId(taskId);
            String t1Key = CarPLCInfoEnum.getCarNoEnum(workingSpanNo,CarEnum.CAR_NO_1.getCarNo()).getMacSN();
            String t2Key = CarPLCInfoEnum.getCarNoEnum(workingSpanNo,CarEnum.CAR_NO_2.getCarNo()).getMacSN();
            String indexT1key = new StringBuilder(workingSpanNo).append("_").append(CarEnum.CAR_NO_1.getCarNo()).toString();
            String indexT2key = new StringBuilder(workingSpanNo).append("_").append(CarEnum.CAR_NO_2.getCarNo()).toString();


            AddTaskConstant.CAR_THREAD_MAP.put(t1Key,t1);
            AddTaskConstant.CAR_THREAD_MAP.put(t2Key,t2);
            AddTaskUtil.updateCarIndex(indexT1key,null);
            AddTaskUtil.updateCarIndex(indexT2key,null);
            AddTaskGuardThread t1GuardThread = AddTaskGuardThread.builder().workingCarKey(indexT1key).otherCarKey(indexT2key)
                    .otherThread(t2).thread(t1).carEnum(CarEnum.CAR_NO_1).build();
            AddTaskGuardThread t2GuardThread = AddTaskGuardThread.builder().workingCarKey(indexT2key)
                    .otherCarKey(indexT1key).otherThread(t1).thread(t2).carEnum(CarEnum.CAR_NO_2).build();
            //守护线程
            ThreadPoolManager.getInstance().execute(t1GuardThread);
            ThreadPoolManager.getInstance().execute(t2GuardThread);
            //启动线程
            t1.start();
            t2.start();
            //ThreadPoolManager.getInstance().execute(t2);
            //ThreadPoolManager.getInstance().execute(t1);



            while (true){
                //两个线程完成工作后，跳出循环
                if(t1.isTaskFinishFlag() && t2.isTaskFinishFlag()){
                    log.info("加料任务taskId：{}对工作跨:{}的天桥系统自己下发任务,双线程干活完成",taskId,workingSpanNo);
                    AddTaskConstant.CAR_THREAD_MAP.remove(t1Key);
                    AddTaskConstant.CAR_THREAD_MAP.remove(t2Key);
                    break;
                }
                try {
                    Thread.sleep(5*1000);

                } catch (Exception e){
                    log.error("加料任务taskId：{}对工作跨:{}的天桥系统自己下发任务,双车联动线程出现异常",taskId,workingSpanNo,e);
                    return;
                }
            }

        }

        //本跨状态变成空闲状态
        AddTaskUtil.updateSpanNoStatus(workingSpanNo,AddTaskConstant.SPAN_STATUS_FREE);


        boolean isSuccess = detailTaskService.allTaskSuccess(taskId);
        String status = isSuccess ? TaskStatusEnum.STATUS_LOAD.getStatus() : TaskStatusEnum.STATUS_ERROR.getStatus();
        //跨区没有值，返回。任务待上料
        Long idKey = Long.valueOf(taskId);
        SysAddPrimaryTaskEntity addPrimaryTask = SysAddPrimaryTaskEntity.builder().idKey(idKey).status(status).build();
        primaryTaskService.updateById(addPrimaryTask);
        AddTaskUtil.TASK_WORKING_MATERIAL_MAP.remove(taskId);
        log.info("加料任务taskId：{}对工作跨:{}的天桥系统自己下发任务,双车联动线程完成",taskId,workingSpanNo);
    }

    @Override
    public void confirmForMES(TaskMaterialOptVO taskMaterialOptVO) {
        String taskId = taskMaterialOptVO.getTaskId();
        String tankCarNo = taskMaterialOptVO.getTankCarNo();
        ProcessMachine machine = SpringUtils.getBean("processMachine");
        AsynTaskExecuteThread thread = AsynTaskExecuteThread.builder().tankCarNo(tankCarNo).taskId(taskId).machine(machine).build();
        ThreadPoolManager.getInstance().execute(thread);
    }

    @Override
    public boolean checkCarStatus(String spanNo) {
        String dregsNO1MacSN = CarPLCInfoEnum.DREGS_STEEL_NO_1.getMacSN();
        String dregsNO2MacSN = CarPLCInfoEnum.DREGS_STEEL_NO_2.getMacSN();

        String wasteNO1MacSN = CarPLCInfoEnum.WASTE_STEEL_NO_1.getMacSN();
        String wasteNO2MacSN = CarPLCInfoEnum.WASTE_STEEL_NO_2.getMacSN();

        String dregsNO1SN = SystemUtils.getCarSNInfoByMacSN(CarPLCInfoEnum.DREGS_STEEL_NO_1.getMacSN());
        String dregsNO2SN = SystemUtils.getCarSNInfoByMacSN(CarPLCInfoEnum.DREGS_STEEL_NO_2.getMacSN());
        String wasteNO1SN = SystemUtils.getCarSNInfoByMacSN(CarPLCInfoEnum.WASTE_STEEL_NO_1.getMacSN());
        String wasteNO2SN = SystemUtils.getCarSNInfoByMacSN(CarPLCInfoEnum.WASTE_STEEL_NO_2.getMacSN());

        //渣钢1号车Map
        Map dregsNO1CarMap = new HashMap(2);
        dregsNO1CarMap.put(GlobalConstant.STRING_SN,dregsNO1SN);

        //渣钢2号车Map
        Map dregsNO2CarMap = new HashMap(2);
        dregsNO2CarMap.put(GlobalConstant.STRING_SN,dregsNO2SN);


        //废钢1号车Map
        Map wasteNO1CarMap = new HashMap(2);
        wasteNO1CarMap.put(GlobalConstant.STRING_SN,wasteNO1SN);


        //废钢2号车Map
        Map wasteNO2CarMap = new HashMap(2);
        wasteNO2CarMap.put(GlobalConstant.STRING_SN,wasteNO2SN);


        if(StringUtils.isEmpty(spanNo)){
            //没有跨区检查四个点位信息
            //检查渣钢1号车状态
            boolean dregsNO1Flag = getCarStatusVal(dregsNO1CarMap, dregsNO1MacSN);
            if(!dregsNO1Flag){
                return false;
            }
            //检查渣钢2号车状态
            boolean dregsNO2Flag = getCarStatusVal(dregsNO2CarMap, dregsNO2MacSN);
            if(!dregsNO2Flag){
                return false;
            }
            //检查废钢1号车状态
            boolean wasteNO1Flag = getCarStatusVal(wasteNO1CarMap, wasteNO1MacSN);
            if(!wasteNO1Flag){
                return false;
            }
            //检查废钢2号车状态
            boolean wasteNO2Flag = getCarStatusVal(wasteNO2CarMap, wasteNO2MacSN);
            if(!wasteNO2Flag){
                return false;
            }
            return true;
        }
        //检查废钢库
        if(AddTaskConstant.WASTE_STEEL_SPAN_NO.equals(spanNo)){
            //检查废钢1号车状态
            boolean wasteNO1Flag = getCarStatusVal(wasteNO1CarMap, wasteNO1MacSN);
            if(!wasteNO1Flag){
                return false;
            }
            //检查废钢2号车状态
            boolean wasteNO2Flag = getCarStatusVal(wasteNO2CarMap, wasteNO2MacSN);
            if(!wasteNO2Flag){
                return false;
            }
            return true;
        }

        if(AddTaskConstant.DREGS_STEEL_SPAN_NO.equals(spanNo)){
            //检查渣钢1号车状态
            boolean dregsNO1Flag = getCarStatusVal(dregsNO1CarMap, dregsNO1MacSN);
            if(!dregsNO1Flag){
                return false;
            }
            //检查渣钢2号车状态
            boolean dregsNO2Flag = getCarStatusVal(dregsNO2CarMap, dregsNO2MacSN);
            if(!dregsNO2Flag){
                return false;
            }
            return true;
        }
        return true;
    }

    @Override
    public void forceFinishTask(String taskId) {

        Iterator<Map.Entry<String, AbstrCarDoingAddTaskThread>> iterator = AddTaskConstant.CAR_THREAD_MAP.entrySet().iterator();
        while (iterator.hasNext()) {
            Map.Entry<String, AbstrCarDoingAddTaskThread> entry = iterator.next();
            AbstrCarDoingAddTaskThread thread = entry.getValue();
            if(taskId.equals(thread.getTaskId())){
                log.info("taskId:{}任务手动停止任务",taskId);
                thread.setTaskFinishFlag(true);
                iterator.remove();
            }

        }

    }

    @Override
    public void fixAbnormal(String carName) throws Exception {
        CarMonitorDotInfoEnum carMonitorDotInfoEnum = CarMonitorDotInfoEnum.getEnumByCarName(carName);

        try {
            PLCWriteRequestParamBO plcWriteRequestParamBO = PLCWriteRequestParamBO.builder().value("true").address(GlobalConstant.FAULT_SET_ADDRESS)
                    .label(carName + GlobalConstant.LABEL_FAULT_SET).macSN(carName).dataType(0).build();
            PLCHttpsUtils.write(RemoteURLConstant.URL_WRITEBC,plcWriteRequestParamBO);

            Thread.sleep(3*1000);

            plcWriteRequestParamBO = PLCWriteRequestParamBO.builder().value("false").address(GlobalConstant.FAULT_SET_ADDRESS)
                    .label(carName + GlobalConstant.LABEL_FAULT_SET).macSN(carName).dataType(0).build();
            PLCHttpsUtils.write(RemoteURLConstant.URL_WRITEBC,plcWriteRequestParamBO);

        } catch (Exception e){
            throw e;
        }


    }

    @Override
    public void resumeTask(String carName) throws Exception {

        CarMonitorDotInfoEnum carMonitorDotInfoEnum = CarMonitorDotInfoEnum.getEnumByCarName(carName);

        try {
            PLCWriteRequestParamBO plcWriteRequestParamBO = PLCWriteRequestParamBO.builder().value("false").address(carMonitorDotInfoEnum.getTaskPauseAddress())
                    .label(carName + GlobalConstant.LABEL_TASK_PAUSE).macSN(carName).dataType(0).build();
            PLCHttpsUtils.write(RemoteURLConstant.URL_WRITEBC,plcWriteRequestParamBO);

        } catch (Exception e){
            throw e;
        }

    }

    @Override
    public void refresh(String taskId) {
        detailTaskService.update(new LambdaUpdateWrapper<SysAddDetailTaskEntity>()
                .eq(SysAddDetailTaskEntity::getTaskId,taskId).set(SysAddDetailTaskEntity::getCreateDate,LocalDateTime.now()));
    }


    private boolean getCarStatusVal(Map carParamMap,String carMacSN){
        carParamMap.put(GlobalConstant.STRING_LABEL,carMacSN + GlobalConstant.CAR_MODEL_LABEL);
        ResponseLabelDataBO data1 = PLCHttpsUtils.sendPost(RemoteURLConstant.URL_READBC, carParamMap, ResponseLabelDataBO.class);
        boolean val1 = getVal(data1);
        if(!val1){
            return val1;
        }
        carParamMap.put(GlobalConstant.STRING_LABEL,carMacSN + GlobalConstant.LIFTING_HIGHEST_LABEL);
        ResponseLabelDataBO data2 = PLCHttpsUtils.sendPost(RemoteURLConstant.URL_READBC, carParamMap, ResponseLabelDataBO.class);
        boolean val2 = getVal(data2);
        if(!val2){
            return val2;
        }
        return true;
    }

    private boolean getVal(ResponseLabelDataBO dregsNO1DataBO) {
        if(dregsNO1DataBO != null){
            Map<String, String> content = dregsNO1DataBO.getContent();
            if(content != null){
                return Boolean.valueOf(content.get("currentVal"));
            }
        }

        return false;
    }

    @Override
    public void increase(String msgBody, long idKey) {
        //槽车
        String slotNo = msgBody.substring(0, 2).trim();
        int num = Integer.valueOf(msgBody.substring(3, 5));
        int length = msgBody.length();
        int year = Integer.valueOf(msgBody.substring(length - 15, length -11));
        int month = Integer.valueOf(msgBody.substring(length - 11, length - 9));
        int day = Integer.valueOf(msgBody.substring(length - 9, length -7));
        int hour = Integer.valueOf(msgBody.substring(length - 7, length -5));
        int minute = Integer.valueOf(msgBody.substring(length - 5, length -3));
        int second = Integer.valueOf(msgBody.substring(length - 3, length - 1));

        LocalDateTime sendDate = LocalDateTime.of(year, month, day, hour, minute, second);
        SysAddPrimaryTaskEntity primaryTaskEntity = SysAddPrimaryTaskEntity.builder()
                .status(TaskStatusEnum.STATUS_UNDOING.getStatus()).taskType(AddTaskConstant.TASK_TYPE_MES)
                .materialNum(num).distributeDate(sendDate).tankCarNo(slotNo).build();
        primaryTaskService.save(primaryTaskEntity);
        String taskId = String.valueOf(primaryTaskEntity.getIdKey());
        int startIndex = 0;
        List<SysAddDetailTaskEntity> list = new ArrayList<>(num);

        for(int i = 0;i < num;i++){
            startIndex = i * 76 + 5;
            String matCode = msgBody.substring( startIndex, 20 + startIndex).trim();
            String matName = msgBody.substring(20 + startIndex , 70 + startIndex).trim();
            float matWt = Float.valueOf(msgBody.substring(startIndex + 70 ,startIndex + 76));
            //单位换算
            matWt = matWt / 1000;
            SysAddDetailTaskEntity detailTaskEntity = SysAddDetailTaskEntity.builder().taskId(taskId).targetWeight(matWt)
                    .materialNo(matCode).materialName(matName).status(TaskStatusEnum.STATUS_UNDOING.getStatus()).build();
            list.add(detailTaskEntity);
        }
        detailTaskService.saveBatch(list);
        //调用责任链
        ProcessContext processContext = new ProcessContext<AddBusinessTaskInfo>();
        AddBusinessTaskInfo processModel = AddBusinessTaskInfo.builder().tankCarNo(slotNo).taskId(taskId).build();
        processContext.setProcessModel(processModel);
        processContext.setCode(BusinessCode.ADD_TASK_CODE.getCode());
        processMachine.process(processContext);
//        ProcessMachine machine = SpringUtils.getBean("processMachine");
//        ThreadPoolManager.getInstance().execute(AsynTaskExecuteThread.builder().tankCarNo(slotNo).taskId(taskId).machine(machine).build());
    }




    @Override
    public void modify(String msgBody) {
        //槽车
        String slotNo = msgBody.substring(0, 2).trim();

        SysAddPrimaryTaskEntity primaryTaskEntity = primaryTaskService.getModifyTask(slotNo);
        String taskId = String.valueOf(primaryTaskEntity.getIdKey());
        List<SysAddDetailTaskEntity> list = detailTaskService.list(new LambdaQueryWrapper<SysAddDetailTaskEntity>()
                .eq(SysAddDetailTaskEntity::getTaskId, taskId));
        boolean res = detailTaskService.modifyWeight(list, msgBody);

        SysAddPrimaryTaskEntity taskEntity = SysAddPrimaryTaskEntity.builder().idKey(primaryTaskEntity.getIdKey()).build();
        if(res){
            taskEntity.setStatus(TaskStatusEnum.STATUS_UNDOING.getStatus());
        } else{
            taskEntity.setErrMsg("更新操作失败");
            taskEntity.setStatus(TaskStatusEnum.STATUS_ERROR.getStatus());
        }
        primaryTaskService.updateById(taskEntity);
        ProcessContext processContext = new ProcessContext<AddBusinessTaskInfo>();
        AddBusinessTaskInfo processModel = AddBusinessTaskInfo.builder().tankCarNo(slotNo).taskId(taskId).build();
        processContext.setProcessModel(processModel);
        processContext.setCode(BusinessCode.ADD_TASK_CODE.getCode());
        processMachine.process(processContext);
//        ProcessMachine machine = SpringUtils.getBean("processMachine");
//        ThreadPoolManager.getInstance().execute(AsynTaskExecuteThread.builder().tankCarNo(slotNo).taskId(taskId).machine(machine).build());
    }


    public void modify(TaskMaterialOptVO materialOptVO) {
        String tankCarNo = materialOptVO.getTankCarNo();
        String taskId = materialOptVO.getTaskId();
        Integer materialNum = materialOptVO.getMaterialNum();
        String spanNo = materialOptVO.getSpanNo();
        SysAddPrimaryTaskEntity primaryTaskEntity = new SysAddPrimaryTaskEntity();
        primaryTaskEntity.setIdKey(Long.valueOf(taskId));
        primaryTaskEntity.setStatus(TaskStatusEnum.STATUS_UNDOING.getStatus());
        primaryTaskService.updateById(primaryTaskEntity);

        AddBusinessTaskInfo processModel = AddBusinessTaskInfo.builder().workingSpanNo(spanNo).materialNum(materialNum).tankCarNo(tankCarNo).taskId(taskId).build();
        if(!AddTaskConstant.CAR_NO_BOTH.equals(materialOptVO.getCarNo())){
            processModel.setFlag(true);
            processModel.setCarNo(materialOptVO.getCarNo());
        }
        this.executeHandTask(processModel);


    }

    @Override
    public void optIncrease(TaskMaterialOptVO taskMaterialOptVO) {
        String taskId = taskMaterialOptVO.getTaskId();
        String tankCarNo = taskMaterialOptVO.getTankCarNo();
        String materialNo = taskMaterialOptVO.getMaterialNo();
        String materialName = taskMaterialOptVO.getMaterialName();
        Float targetWeight = taskMaterialOptVO.getTargetWeight();
        if(StringUtils.isEmpty(taskId)){
            //前端没有传任务id，说明为新增一个基础任务  任务暂时写成临时任务号
            taskId = AddTaskConstant.TEMP_TASK_ID;
        }
        SysAddDetailTaskEntity addDetailTask = SysAddDetailTaskEntity.builder().taskId(taskId).tankCarNo(tankCarNo).materialName(materialName)
                .materialNo(materialNo).targetWeight(targetWeight).build();
        detailTaskService.save(addDetailTask);

    }

    @Override
    public void optModify(TaskMaterialOptVO materialOptVO) {
        String idKey = materialOptVO.getIdKey();
        Float targetWeight = materialOptVO.getTargetWeight();
        SysAddDetailTaskEntity updateEntity = SysAddDetailTaskEntity.builder().idKey(Long.valueOf(idKey))
                .status(materialOptVO.getStatus()).targetWeight(targetWeight).errMsg("").build();
        detailTaskService.updateById(updateEntity);
    }

    @Override
    public void frontConfirm(TaskMaterialOptVO taskMaterialOptVO) {
//        String oprType = taskMaterialOptVO.getOprType();
//        TaskTypeEnum taskTypeEnum = TaskTypeEnum.getEnumByType(oprType);
//        taskTypeEnum.frontConfirm(this,taskMaterialOptVO);
        String taskId = taskMaterialOptVO.getTaskId();
        String tankCarNo = taskMaterialOptVO.getTankCarNo();
        List<SysAddDetailTaskEntity> list = detailTaskService.getDetailTaskInfo(tankCarNo,taskId);
        //子任务个数
        int num = list.size();

        SysAddPrimaryTaskEntity primaryTaskEntity = SysAddPrimaryTaskEntity.builder().idKey(Long.valueOf(taskId))
                .status(TaskStatusEnum.STATUS_DOING.getStatus()).materialNum(num)
                .distributeDate(LocalDateTime.now()).tankCarNo(tankCarNo).build();
        primaryTaskService.updateById(primaryTaskEntity);
        AddBusinessTaskInfo taskInfo = AddBusinessTaskInfo.builder().taskId(taskId).tankCarNo(tankCarNo)
                .workingSpanNo(taskMaterialOptVO.getSpanNo()).test("1").build();
        if(!AddTaskConstant.CAR_NO_BOTH.equals(taskMaterialOptVO.getCarNo())){
            taskInfo.setFlag(true);
            taskInfo.setCarNo(taskMaterialOptVO.getCarNo());
        }

        this.executeHandTask(taskInfo);

    }

    @Override
    public void completeTask(String tankCarNo,String idKey) {
        SysAddPrimaryTaskEntity primaryTaskEntity = SysAddPrimaryTaskEntity.builder().idKey(Long.valueOf(idKey))
                .status(TaskStatusEnum.STATUS_COMPLETE.getStatus()).build();
        primaryTaskService.updateById(primaryTaskEntity);
        TankCarNoEnum tankCarNoEnum = TankCarNoEnum.getEnum(tankCarNo);
        TankCarTaskInfoBO taskInfoBO = TankCarTaskInfoBO.builder().taskType(AddTaskConstant.TANK_CAR_TASK_TYPE_UNLOAD).spanNo(tankCarNo).build();
        //添加至槽车队列中，槽车移动
        AddTaskConstant.TANK_CAR_QUEUE_MAP.get(tankCarNoEnum.getTankCarNo()).add(taskInfoBO);

    }


}
